using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using UnityEngine;

namespace M13.Utility
{
    public class ByteWriter
    {
        int _i;

        public void ReSetWriter() { _i = 0; }

        public void SetWriter(int startIndex) { _i = startIndex; }

        public void Write(byte[] scrArray, byte v)
        {
            scrArray[_i++] = v;
        }

        public void Write(byte[] scrArray, bool v)
        {
            if (v) scrArray[_i++] = 0x01;
            else scrArray[_i++] = 0x00;
        }

        public void Write(byte[] scrArray, ushort v)
        {
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
        }

        public void Write(byte[] scrArray, int v)
        {
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
            scrArray[_i++] = (byte)(v >> 16);
            scrArray[_i++] = (byte)(v >> 24);
        }
        public void Write(byte[] scrArray, int v, int startIndex)
        {
            _i = startIndex;
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
            scrArray[_i++] = (byte)(v >> 16);
            scrArray[_i++] = (byte)(v >> 24);
        }

        public void Write(byte[] scrArray, uint v)
        {
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
            scrArray[_i++] = (byte)(v >> 16);
            scrArray[_i++] = (byte)(v >> 24);
        }

        public void Write(byte[] scrArray, long v)
        {
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
            scrArray[_i++] = (byte)(v >> 16);
            scrArray[_i++] = (byte)(v >> 24);
            scrArray[_i++] = (byte)(v >> 32);
            scrArray[_i++] = (byte)(v >> 40);
            scrArray[_i++] = (byte)(v >> 48);
            scrArray[_i++] = (byte)(v >> 56);
        }

        public void Write(byte[] scrArray, ulong v)
        {
            scrArray[_i++] = (byte)v;
            scrArray[_i++] = (byte)(v >> 8);
            scrArray[_i++] = (byte)(v >> 16);
            scrArray[_i++] = (byte)(v >> 24);
            scrArray[_i++] = (byte)(v >> 32);
            scrArray[_i++] = (byte)(v >> 40);
            scrArray[_i++] = (byte)(v >> 48);
            scrArray[_i++] = (byte)(v >> 56);
        }

        public void Write(byte[] scrArray, float v)
        {
            Write(scrArray, BitConverter.GetBytes(v));
        }

        public void Write(byte[] scrArray, float v, int indexOffset)
        {
            Write(scrArray, BitConverter.GetBytes(v), indexOffset);
        }

        public void Write(byte[] scrArray, double v)
        {
            Write(scrArray, BitConverter.GetBytes(v));
        }

        public void Write(byte[] scrArray, string v)
        {
            byte[] strBytes = System.Text.Encoding.Default.GetBytes(v);
            int len = strBytes.Length;
            Write(scrArray, len);

            for (int j = 0; j < len; j++)
            {
                scrArray[_i++] = strBytes[j];
            }
        }

        public void Write(byte[] scrArray, byte[] v)
        {
            for (int j = 0; j < v.Length; j++)
            {
                scrArray[_i++] = v[j];
            }
        }

        public void Write(byte[] scrArray, byte[] v, int indexOffset)
        {
            for (int j = 0; j < v.Length; j++)
            {
                scrArray[indexOffset++] = v[j];
            }
        }

        public void Write(byte[] scrArray, int[] v)
        {
            for(int j = 0; j < v.Length; j++)
            {
                scrArray[_i++] = (byte)v[j];
                scrArray[_i++] = (byte)(v[j] >> 8);
                scrArray[_i++] = (byte)(v[j] >> 16);
                scrArray[_i++] = (byte)(v[j] >> 24);
            }
        }

        public void Write(byte[] scrArray, int[] v, int indexOffset)
        {
            _i = indexOffset;
            for (int j = 0; j < v.Length; j++)
            {
                scrArray[_i++] = (byte)v[j];
                scrArray[_i++] = (byte)(v[j] >> 8);
                scrArray[_i++] = (byte)(v[j] >> 16);
                scrArray[_i++] = (byte)(v[j] >> 24);
            }
        }

        public void Write(byte[] scrArray, float[] v, int indexOffset)
        {
            for(int j = 0; j < v.Length; j++)
            {
                Write(scrArray, v[j], indexOffset);
            }
        }
    }
}